<template>
  <view class="flex flex-wrap">
    <view v-for="(item, index) in previewList" :key="index" class="mr-3 mb-2 relative border rounded"
      @click="previewImages">
      <u-image :src="item" width="180" height="180" />
      <view @click.stop="delImage(index)">
        <u-icon name="close-circle-fill" size="40" color="#fa3545"
          class="absolute -right-2 -top-2 bg-white rounded-full" />
      </view>
    </view>
    <view style="width: 180rpx;height:180rpx" class="border rounded flex items-center justify-center" @click="addImage"
      v-if="previewList.length < maxCount">
      <u-icon name="plus" size="50" color="#909399" />
    </view>
  </view>
</template>

<script>
import Compressor from 'compressorjs'
import { blobToDataURI } from '../../utils/fileUtil'
export default {
  name: "yer-image-upload",
  props: {
    defaultValue: "", //默认显示的字典，传字典的代码项
    defaultValueExtra: "", //默认显示的字典，传字典的代码项
    deletable: {
      type: Boolean,
      default: true,
    }, //是否展示删除按钮
    maxCount: {
      type: Number,
      default: 9
    },
    header: {
      type: Object,
      default: () => {
        return {}
      }
    },
    uploadFormData: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 上传模式  filestream
    mode: {
      type: String,
      default: 'base64' // 文件上传模式  filestream  base64
    },
    // 值模式
    valueType: {
      type: String,
      default: 'string' // 值类型  array  string
    },
    action: {
      type: String,
      default: "",
    }, //请求地址
    evalPath: {
      type: String,
      default: "",
    },
    prefix: { // 图片预览前缀 
      type: String,
      default: "",
    }
  },
  emits: ["update:modelValue", "input", "change"],
  data() {
    return {
      list: [],
      previewList: []
    }
  },
  computed: {
    // previewList() {
    //   const arr = []
    //   for (const item of this.list) {
    //     arr.push(this.prefix + item)
    //   }
    //   return arr
    // }
  },
  methods: {
    // 预览文件
    previewImages() {
      const showList = []
      this.previewList.forEach(element => {
        showList.push(element)
      });
      uni.previewImage({
        urls: showList,
        success: (result) => { },
        fail: (error) => { }
      })
    },
    // 上传文件
    uploadImage(filePath) {
      // console.log('filePath', filePath);
      uni.showLoading({
        title: '图片上传中...',
        mask: true
      })
      uni.uploadFile({
        url: this.action,
        fileType: 'image',
        filePath: filePath,
        name: 'file',
        header: this.header,
        formData: this.uploadFormData,
        success: ({ data, statusCode }) => {
          uni.hideLoading();
          // console.log('返回结果', data);
          const res = JSON.parse(data);
          const result = this.myEval(res, this.evalPath)
          // console.log(result);
          if (result) {
            // console.log(result);
            this.list.push(result)
            this.previewList.push(filePath)
          } else {
            uni.showToast({
              title: res.message,
              icon: 'error',
              mask: true
            })
          }
        },
        fail: (error) => {
          uni.hideLoading();
          uni.showToast({
            title: '上传失败',
            icon: 'error',
            mask: true
          })
        }
      })
    },
    // 删除照片
    delImage(index) {
      this.list.splice(index, 1)
      this.previewList.splice(index, 1)
    },
    // 新增图片
    addImage() {
      const _this = this
      uni.chooseImage({
        sizeType: ['original', 'compressed'],
        sourceType: ['album', 'camera'],
        success: async ({ tempFilePaths, tempFiles }) => {
          // console.log('tempFilePaths', tempFilePaths);
          // console.log(tempFiles);
          let newBlob = tempFiles[0]

          newBlob = await _this.compressImage(tempFilePaths[0], tempFiles[0]) // H5 返回blob  wx 返回的是 url
          // console.log("压缩结果", newBlob);

          // 如果是base64模式 把blob转成base64字符串
          // console.log("mode",this.mode);
          if (this.mode == 'base64') {
            // 转成base64
            let base64Res = ''
            // #ifdef H5
            base64Res = await blobToDataURI(newBlob)
            // #endif
            // #ifdef MP-WEIXIN
            base64Res = wx.getFileSystemManager().readFileSync(newBlob, "base64")
            // console.log('小程序转base64',base64Res);
            // #endif
            this.list.push(base64Res)
            this.previewList.push(base64Res)
          } else {
            // console.log("进行上传");
            // #ifdef H5
            newBlob = URL.createObjectURL(newBlob)
            // #endif
            this.uploadImage(newBlob)
          }
        },
        fail: (error) => {
          console.log(error);
        }
      })
    },
    // 压缩图片
    // compressH5(blob) {
    //   return new Promise((resolve, reject) => {
    //     if (blob.size > 2000000) {
    //       uni.showLoading({
    //         title: '图片压缩中...',
    //         mask: true
    //       })
    //       new Compressor(blob, {
    //         quality: 0.6,
    //         success(result) {
    //           uni.hideLoading();
    //           // console.log("压缩后的尺寸", result.size);
    //           // 如果压缩完还大于2M 就提示
    //           if (result.size > 2000000) {
    //             uni.showToast({
    //               title: '上传图片不能大于16M',
    //               icon: 'none',
    //               mask: true
    //             })
    //             reject("上传图片过大")
    //           } else {
    //             resolve(result)
    //           }
    //         },
    //         error(err) {
    //           uni.hideLoading();
    //           reject(err)
    //         },
    //       });
    //     } else {
    //       resolve(blob)
    //     }

    //   })
    // },
    // 图片压缩
    compressImage(filePath, file) {
      const _this = this
      return new Promise((resolve, reject) => {
        // console.log('file', file)
        // console.log('fileSize', file.size)
        let quality = 1
        if (file.size > 8 * 1024 * 1024) {
          uni.showToast({
            title: '上传图片不能大于8M',
            icon: 'none',
            mask: true
          })
          reject(new Error('传图片不能大于8M'))
        } else if (file.size > 4 * 1024 * 1024) {
          quality = 0.15
        } else if (file.size > 2 * 1024 * 1024) {
          quality = 0.25
        }
        // #ifdef MP-WEIXIN
        // 获取图片的宽度
        wx.getImageInfo({
          src: filePath,
          async success(res) {
            // console.log('微信压缩后大小', res)
            const width = res.width * quality
            const wxTempPath = await _this.wxCompressImage(filePath, width)
            // console.log('wxTempPath', wxTempPath)
            resolve(wxTempPath)
          }
        })

        // #endif
        // #ifdef H5
        const compressor = new Compressor(file, {
          quality,
          success(result) {
            uni.hideLoading()
            // console.log("压缩后的尺寸", result.size);
            // 如果压缩完还大于2M 就提示
            // console.log('H5压缩完大小', result.size)
            resolve(result)
          },
          error(err) {
            uni.hideLoading()
            reject(err)
          }
        })
        // #endif
      })
    },
    // 微信获取图片信息
    wxCompressImage (filePath, width) {
      return new Promise((resolve, reject) => {
        uni.compressImage({
          src: filePath,
          compressedWidth: width,
          success: (res) => {
            // wx.getImageInfo({
            //   src: res.tempFilePath,
            //   success(res) {
            //     console.log('微信压缩后大小', res)
            //   }
            // })
            resolve(res.tempFilePath)
          },
          fail: (err) => {
            console.log('小程序压缩失败', err)
            reject(err)
          }
        })
      })
    },
    translateArr(arr) {
      let str = "";
      if (arr && arr.length > 0) {
        for (let i = 0; i < arr.length; i++) {
          str += arr[i] + ",";
        }
      }
      if (str.length > 0) {
        str = str.substring(0, str.length - 1);
      }

      return str;
    },
    myEval(res, evalPath) {
      const evalArr = evalPath.split(".")
      let i = 0
      while (i < evalArr.length) {
        res = res[evalArr[i]]
        i++
      }
      return res
    }
  },
  watch: {
    list: {
      deep: true,
      handler: function (n, o) {
        // 如果值类型是array
        if (this.valueType == 'array') {
          this.$emit("update:modelValue", n);
          this.$emit("input", n);
          this.$emit('change',n)
        } else {
          this.$emit("update:modelValue", this.translateArr(n));
          this.$emit("input", this.translateArr(n));
          this.$emit('change',n)
        }
      }
    },
    defaultValue: {
      immediate: true,
      handler: function (newVal, oldVal) {
        // console.log('newVal', newVal);
        const _this = this
        if (newVal && newVal != 'undefined') {
          this.value = newVal;
          let tempArr = []
          if (this.valueType == 'array') {
            tempArr = newVal
          } else {
            tempArr = newVal.split(',')
          }
          this.list = tempArr
          for (const item of tempArr) {
            this.previewList.push(this.prefix + item)
          }
        }
      },
    }
  },
};
</script>

<style scoped>
.flex-1 {
  flex: 1
}

.flex-wrap {
  flex-wrap: wrap;
}

.flex {
  display: flex;
}

.items-center {
  align-items: center
}

.justify-center {
  justify-content: center
}

.justify-between {
  justify-content: space-between;
}

.font-bold {
  font-weight: bold
}

.py-1\.5 {
  padding: 12rpx 0;
}

.px-3 {
  padding: 0 24rpx;
}

.mr-1 {
  margin-right: 8rpx;
}

.mr-3 {
  margin-right: 24rpx;
}

.mb-2 {
  margin-bottom: 16rpx;
}

.relative {
  position: relative;
}

.text-green-600 {
  color: #059669;
}

.border {
  border-width: 1px;
  border-style: solid;
  border-color: rgb(229 231 235);
}

.border-b {
  border-bottom-width: 1px;
  border-bottom-style: solid;
  border-bottom-color: rgb(229 231 235);
}

.rounded {
  border-radius: 8rpx;
}

.absolute {
  position: absolute;
}

.-right-2 {
  right: -16rpx;
}

.bg-white {
  background-color: #FFFFFF;
}

.-top-2 {
  top: -16rpx
}

.rounded-full {
  border-radius: 99999px;
}

.pb-3 {
  padding-bottom: 24rpx;
}
</style>
